<?php

/**
 * 
 * @author Kartik
 *
 * Try creating a priceMetrics and priceMetricType field which will them reduce the confusion will storing the data.
 */

class Buyback_Model_Offer{

	const EMPTY_ISBN_LIST = "The isbn list is empty and cannot be used to create an offer";
	const INVALID_ISBN = "The Isbn you have entered is invalid";
	const NO_OFFER = "There was no offer generated for the isbn you have entered";
	const NO_DATA = "There was no information available for the isbn you have entered";
	
	
	/**
	 * @var string_array
	 * facilitates easier api correspondance with Amazon
	 */
	public $isbnString = array();
	
	/**
	 * @var array 
	 * keeps track of all ISBNs entered by the user
	 */
	public $isbnCount = array();
	
	
	/**
	 * @var Buyback_Model_Cart
	 */
	protected $_cartModel;
	
	/**
	 * @var Buyback_Resource_Offer_Amazon
	 */
	protected $_amzOffer;
	
	/**
	 * @var Buyback_Resource_Offer_MBS
	 */
	protected $_mbsOffer;
		
	public $_items = array();
		
	public function init(){
		$this->_cartModel = new Buyback_Model_Cart();
	}
	
	/**
	 * @param array $isbnList
	 * @throws Exception
	 * Compile list of isbns sent by user
	 */
	public function __construct(array $isbnList = array()){
		
		$this->init();
		
		if(null == $isbnList)
		{
			return false;
		}
		
		//Zend Validate function set to Auto
		$isbnCheck = new Zend_Validate_Isbn();
		
		//Creates an array to track quantity of ISBNs
		foreach($isbnList as $isbn){
			if(10 == strlen($isbn))
				$isbn = Custom_ConvertIsbn::convertIsbn10to13($isbn);
			if($isbnCheck->isValid($isbn)){
				if(isset($this->isbnCount[$isbn])){
					$this->isbnCount[$isbn]++;
				}else{
					$this->isbnCount[$isbn] = 1;
				}
			}else{
				if(''!= $isbn)
					$this->_items[$isbn] = $this->_cartModel->addInvalidItem($isbn, self::INVALID_ISBN);
			}
		}
		
		
		//Creates a batch of strings of 10 ISBNs to reduce the turnaround time for the Amazon request
		$count = 0;
		foreach($this->isbnCount as $key => $value){
			if($this->checkCartAndUpdate($key, $value)){
				unset($this->isbnCount[$key]);
			}else{
				if(isset($this->isbnString[$count/10])){
					$this->isbnString[$count/10] .= ',' . $key;
				}else{
					$this->isbnString[$count/10] = $key;
				}
				$count++;
			}
		}
	}
	
	//check if item already exists then update it. and remove it from list.
	public function checkCartAndUpdate($isbn, $qntyAsked){
 
		if($this->_cartModel->offSetExists($isbn) && ("Invalid Item" != $this->_cartModel->offsetGet($isbn)->ItemType)){
			
			$maxQnty = $this->_cartModel->offsetGet($isbn)->MaxQnty;
			$qntyPresent = $this->_cartModel->offsetGet($isbn)->Quantity;
			
			//Accept smaller of two quantities
			$qntyToAdd = ($maxQnty <=($qntyPresent+$qntyAsked))? $maxQnty:$qntyAsked+$qntyPresent; 
			
			$this->_cartModel->updateCartItem($isbn, $qntyToAdd);
		}
		
		return $this->_cartModel->offSetExists($isbn);
	}
	
	public function createOffer(){
		$amzOffer = $this->getAmazonOffer()->getOffer($this->isbnString); 
		$mbsOffer = $this->getMBSOffer()->getOffer($this->isbnString);
		
		/*
		 * Compare prices
		 * then
		 * Select One of the data sources.
		 */
		foreach($this->isbnCount as $isbn => $qnty){
			
			$amzOfferPrice = $mbsOfferPrice = 0;
			if(array_key_exists($isbn, $amzOffer)){
				$amzOfferPrice = $amzOffer[$isbn]->Offers->OfferPrice;
			}
			if(array_key_exists($isbn, $mbsOffer)){
				$mbsOfferPrice = isset($mbsOffer[$isbn]->Offers->OfferPrice)?$mbsOffer[$isbn]->Offers->OfferPrice:0;
			}
			
			$offerPrice = new Buyback_Resource_Offer_OfferPrice(
				array(
					'A' =>	$amzOfferPrice,
					'M' =>	$mbsOfferPrice
				)			
			);
			
			if(0 == $offerPrice->getOfferPrice()){
				
				$result = Doctrine_Model_WhiteList::fetchBook($amzOffer[$isbn]);
				//Access WhiteList to get Offer
				
				if(0 == $result->price or 0 == $result->maxQnty){
					$this->_items[$isbn] = $this->_cartModel->addInvalidItem($isbn, self::NO_OFFER);					
				}
				
				$offerPrice->setOfferPrice($result->price);
				$offerPrice->setOfferPriceSource('W');
				$maxqnty = $result->maxQnty;
			}
			
			//Call Quantity Limiter Function
			//Temporary fix
			switch($offerPrice->getOfferpriceSource()){
				case 'W':
				case 'A':
					$metric = $amzOffer[$isbn]->Metric;
					break;
				case 'M':
					$metric = $mbsOffer[$isbn]->Metric;
					break;
				
			}
			
			$maxqnty = Buyback_Resource_Offer_Quantity::getMaxQnty($offerPrice->getOfferPriceSource(), $metric);
			//Accept the smaller of the two quantities
			$qntyToAdd = ($maxqnty>=$qnty)?$qnty:$maxqnty;
			
			//Create Data Object to be added to the cart
			if(array_key_exists($isbn, $amzOffer)){
				$offerItem = new Buyback_Resource_Offer_Item($offerPrice->getOfferPriceSource(), $amzOffer[$isbn], $offerPrice->getOfferPrice(), $metric, $qnty, $maxqnty);
			}else if(array_key_exists($isbn, $mbsOffer)){
				$offerItem = new Buyback_Resource_Offer_Item($offerPrice->getOfferPriceSource(), $mbsOffer[$isbn], $offerPrice->getOfferPrice(), $metric, $qnty, $maxqnty);
			}else{
				$this->_items[$isbn] = self::NO_DATA;
				$this->_cartModel->addInvalidItem($isbn, self::NO_DATA);
			}
			
			$this->_items[$isbn] = $this->_cartModel->addValidItem($offerItem);
		}		
		return $this->_items;
	}

	
	public function getAmazonOffer(){
		if(null == $this->_amzOffer){
			$this->setAmazonOffer();
		}
		return ($this->_amzOffer);
	}
	
	public function setAmazonOffer(){
		$this->_amzOffer = new Buyback_Resource_Offer_Amazon();
	}
	
	public function getMBSOffer(){
		if(null == $this->_mbsOffer){
			$this->setMBSOffer();
		}
		return ($this->_mbsOffer);
	}
	
	public function setMBSOffer()
	{
		$this->_mbsOffer = new Buyback_Resource_Offer_MBS();
	}
	
}